package com.ywu.bpmn.flow.service;

import com.ywu.boot.context.YwuContext;
import com.ywu.boot.context.YwuContextHolder;
import com.ywu.bpmn.flow.data.YwuFlowDefinitionRepository;
import com.ywu.bpmn.flow.data.YwuFlowInstanceRepository;
import com.ywu.bpmn.flow.dto.YwuFlowInstanceCommonDto;
import com.ywu.bpmn.flow.dto.YwuFlowInstanceDto;
import com.ywu.bpmn.flow.entity.YwuFlowDefinitionEntity;
import com.ywu.bpmn.flow.entity.YwuFlowInstanceEntity;
import com.ywu.bpmn.flow.entity.YwuFlowTaskEntity;
import com.ywu.bpmn.form.service.dto.YwuFormInstanceDto;
import com.ywu.bpmn.form.service.service.YwuFormInstanceService;
import com.ywu.bpmn.spi.dto.YwuBpmnDto;
import com.ywu.bpmn.spi.spi.YwuActivitiSpi;
import com.ywu.common.result.CommonResult;
import com.ywu.common.utils.TimerIdGenerateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName YwuFlowInstanceService
 * @Description TODO
 * @Author GroundDemo
 * @Date 2025/4/23 15:45
 * @Version 1.0
 **/
@Service
public class YwuFlowInstanceService {
    @Autowired
    private YwuFlowInstanceRepository repository;

    @Autowired
    private YwuFlowDefinitionRepository definitionRepository;

    @Autowired
    private YwuFormInstanceService formInstanceService;

    @Autowired
    private YwuActivitiSpi spi;

    /**
    * @Author GroundDemo
    * @Description 查询代办的流程列表
    * @Date 15:46 2025/4/23
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> flowTodoList(YwuFlowInstanceCommonDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        dto.setUserAccount(currentContext.getYwuContextUser().getUserAccount());
        List<YwuFlowInstanceCommonDto> resList = repository.queryFlowTodoList(dto);
        return CommonResult.success(resList);
    }

    /**
    * @Author GroundDemo
    * @Description 流程实例代办列表
    * @Date 16:01 2025/4/23
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> instanceTodoList(YwuFlowInstanceCommonDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        dto.setUserAccount(currentContext.getYwuContextUser().getUserAccount());
        List<YwuFlowInstanceCommonDto> resList = repository.queryInstanceTodoList(dto);
        return CommonResult.success(resList);
    }

    /**
    * @Author GroundDemo
    * @Description 发起流程
    * @Date 18:05 2025/4/23
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    @Transactional
    public CommonResult<Object> startInstance(YwuFlowInstanceCommonDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 判断当前是否存在该流程
        YwuFlowDefinitionEntity search = new YwuFlowDefinitionEntity();
        search.setId(dto.getFlowId());
        search.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        YwuFlowDefinitionEntity entity = definitionRepository.getEntity(search);
        if (Objects.isNull(entity)) {
            return CommonResult.error().setErrorCode("flow.is.not.exist");
        }
        // 判读当前是否已经发布
        if (entity.getStatus().equals(YwuFlowDefinitionEntity.DRAFT_STATUS)) {
            return CommonResult.error().setErrorCode("can.not.start.draft.flow");
        }
        // 创建表单实例
        YwuFormInstanceDto ywuFormInstanceDto = new YwuFormInstanceDto();
        ywuFormInstanceDto.setFormId(entity.getFormId());
        ywuFormInstanceDto.setFormInstanceJson(dto.getFormInstanceJson());
        ywuFormInstanceDto.setFormVersion(String.valueOf(entity.getCurrentVersion()));
        CommonResult<Object> result = formInstanceService.addFormInstance(ywuFormInstanceDto);
        if (Objects.isNull(result) || !"200".equals(result.getCode())) {
            return CommonResult.error().setErrorCode("form.instance.create.error");
        }
        // 构建流程实例对象，实例状态为STARTING
        YwuFlowInstanceEntity insert = new YwuFlowInstanceEntity();
        insert.setId(TimerIdGenerateUtil.nextId());
        insert.setFlowId(entity.getId());
        insert.setFlowVersion(String.valueOf(entity.getCurrentVersion()));
        insert.setFormInstanceId((String) result.getData());
        insert.setStatus(YwuFlowInstanceEntity.STARING_STATUS);
        insert.createInfo(currentContext.getYwuContextUser().getUserAccount());
        insert.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        insert.setCurrentNode("nid-start");
        repository.insert(insert);
        // 调用引擎的spi，发起流程
        YwuBpmnDto ywuBpmnDto = new YwuBpmnDto();
        ywuBpmnDto.setKey("flow_" + entity.getId());
        // 构建表单变量
        Map<String, Object> variable = new HashMap<>();
        variable.put("startBy", currentContext.getYwuContextUser().getUserAccount());
        variable.put("instanceId", insert.getId());
        ywuBpmnDto.setVariable(variable);
        spi.start(ywuBpmnDto);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 查询流程实例详情，包括表单构建Json、流程构建JSON，表单实例数据
    * @Date 22:59 2025/4/23
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryInstanceDetailInfo(YwuFlowInstanceCommonDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        dto.setUserAccount(currentContext.getYwuContextUser().getUserAccount());
        dto.setStatus(YwuFlowTaskEntity.RUNNING_STATUS);
        dto.setTaskId(dto.getTaskId());
        YwuFlowInstanceCommonDto ywuFlowInstanceCommonDto = repository.queryInstanceDetailInfo(dto);
        return CommonResult.success(ywuFlowInstanceCommonDto);
    }

    /**
    * @Author GroundDemo
    * @Description 审批流程
    * @Date 10:53 2025/4/24
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    @Transactional
    public CommonResult<Object> completeInstance(YwuFlowInstanceCommonDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 判断当前任务ID是否为当前责任人
        YwuFlowTaskEntity ywuFlowTaskEntity = new YwuFlowTaskEntity();
        ywuFlowTaskEntity.setAssignee(currentContext.getYwuContextUser().getUserAccount());
        ywuFlowTaskEntity.setFlowInstanceId(dto.getId());
        ywuFlowTaskEntity.setTaskId(dto.getTaskId());
        YwuFlowTaskEntity queryRes = repository.getTaskInfoByInstanceIdAndAssignee(ywuFlowTaskEntity);
        // 如果查询结果为空，则表示当前用户无法审批，返回异常
        if (Objects.isNull(queryRes)) {
            return CommonResult.error().setErrorCode("current.node.user.can.not.complete");
        }
        // 获取表单实例信息, 并修改表单实例信息
        YwuFlowInstanceEntity searchInstance = new YwuFlowInstanceEntity();
        searchInstance.setId(dto.getId());
        YwuFlowInstanceCommonDto instanceById = repository.getInstanceAndFlowInfoByInstanceId(searchInstance);
        // 根据表单实例ID修改表单实例数据
        YwuFormInstanceDto ywuFormInstanceDto = new YwuFormInstanceDto();
        ywuFormInstanceDto.setId(instanceById.getFormInstanceId());
        ywuFormInstanceDto.setFormInstanceJson(dto.getFormInstanceJson());
        ywuFormInstanceDto.setFormId(instanceById.getFormId());
        CommonResult<Object> result = formInstanceService.updateFormInstance(ywuFormInstanceDto);
        if (Objects.isNull(result) || !"200".equals(result.getCode())) {
            return CommonResult.error().setErrorCode("form.instance.update.error");
        }
        // 调用引擎侧进行审批
        YwuBpmnDto ywuBpmnDto = new YwuBpmnDto();
        ywuBpmnDto.setTaskId(queryRes.getTaskId());
        spi.complete(ywuBpmnDto);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 查询审批历史流程列表
    * @Date 20:31 2025/4/24
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryCompleteHistoryFlowList(YwuFlowInstanceCommonDto dto) {
        return null;
    }
}
